/*-------------------------------------------------------------------------
 *
 * remote_commands.h
 *	  Helpers to execute commands on remote nodes, over libpq.
 *
 * Copyright (c) Citus Data, Inc.
 *
 *-------------------------------------------------------------------------
 */

#ifndef REMOTE_COMMAND_H
#define REMOTE_COMMAND_H

#include "distributed/connection_management.h"

/* errors which ExecuteRemoteCommand might return */
#define RESPONSE_OKAY 0
#define QUERY_SEND_FAILED 1
#define RESPONSE_NOT_OKAY 2

/* simple helpers */
extern bool IsResponseOK(PGresult* result);
extern void ForgetResults(MultiConnection* connection);
extern bool ClearResults(MultiConnection* connection, bool raiseErrors);
extern bool ClearResultsDiscardWarnings(MultiConnection* connection, bool raiseErrors);
extern bool ClearResultsIfReady(MultiConnection* connection);

/* report errors & warnings */
extern void ReportConnectionError(MultiConnection* connection, int elevel);
extern void ReportResultError(MultiConnection* connection, PGresult* result, int elevel);
extern char* pchomp(const char* in);
extern void LogRemoteCommand(MultiConnection* connection, const char* command);
extern bool CommandMatchesLogGrepPattern(const char* command);

/* wrappers around libpq functions, with command logging support */
extern void ExecuteCriticalRemoteCommandList(MultiConnection* connection,
                                             List* commandList);
extern void ExecuteCriticalRemoteCommand(MultiConnection* connection,
                                         const char* command);
extern void ExecuteRemoteCommandInConnectionList(List* nodeConnectionList,
                                                 const char* command);
extern bool ExecuteRemoteCommandAndCheckResult(MultiConnection* connection, char* command,
                                               char* expected);
extern int ExecuteOptionalRemoteCommand(MultiConnection* connection, const char* command,
                                        PGresult** result);
extern int SendRemoteCommand(MultiConnection* connection, const char* command);
extern int SendRemoteCommandParams(MultiConnection* connection, const char* command,
                                   int parameterCount, const Oid* parameterTypes,
                                   const char* const* parameterValues,
                                   bool binaryResults);
extern List* ReadFirstColumnAsText(PGresult* queryResult);
extern PGresult* GetRemoteCommandResult(MultiConnection* connection,
                                        bool raiseInterrupts);
extern bool PutRemoteCopyData(MultiConnection* connection, const char* buffer,
                              int nbytes);
extern bool PutRemoteCopyEnd(MultiConnection* connection, const char* errormsg);

/* waiting for multiple command results */
extern void WaitForAllConnections(List* connectionList, bool raiseInterrupts);

extern bool SendCancelationRequest(MultiConnection* connection);

extern bool EvaluateSingleQueryResult(MultiConnection* connection, PGresult* queryResult,
                                      StringInfo queryResultString);
extern void StoreErrorMessage(MultiConnection* connection, StringInfo queryResultString);

extern bool IsSettingSafeToPropagate(const char* name);

#endif /* REMOTE_COMMAND_H */
